package service

import (
	"errors"
	"github.com/yourusername/book-management-system/internal/domain/model"
	"github.com/yourusername/book-management-system/internal/domain/repository"
	"github.com/yourusername/book-management-system/pkg/dto"
	"time"
)

type BookService struct {
	bookRepo   repository.BookRepository
	borrowRepo repository.BorrowRepository
}

func NewBookService(br repository.BookRepository, bor repository.BorrowRepository) *BookService {
	return &BookService{bookRepo: br, borrowRepo: bor}
}

func (s *BookService) CreateBook(bookDto dto.BookCreateDTO) (*model.Book, error) {
	// 检查ISBN是否已存在
	existing, err := s.bookRepo.FindByISBN(bookDto.ISBN)
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, err
	}
	if existing != nil {
		return nil, errors.New("book with this ISBN already exists")
	}

	book := &model.Book{
		ISBN:        bookDto.ISBN,
		Title:       bookDto.Title,
		Author:      bookDto.Author,
		Description: bookDto.Description,
		PublishDate: bookDto.PublishDate,
		Status:      model.Available,
	}

	if err := s.bookRepo.Create(book); err != nil {
		return nil, err
	}

	return book, nil
}

func (s *BookService) GetBookByID(id uint) (*model.Book, error) {
	return s.bookRepo.FindByID(id)
}

func (s *BookService) UpdateBook(id uint, bookDto dto.BookUpdateDTO) (*model.Book, error) {
	book, err := s.bookRepo.FindByID(id)
	if err != nil {
		return nil, err
	}

	// 更新可修改字段
	book.Title = bookDto.Title
	book.Author = bookDto.Author
	book.Description = bookDto.Description
	book.PublishDate = bookDto.PublishDate

	if err := s.bookRepo.Update(book); err != nil {
		return nil, err
	}

	return book, nil
}

func (s *BookService) DeleteBook(id uint) error {
	// 检查图书是否被借出
	book, err := s.bookRepo.FindByID(id)
	if err != nil {
		return err
	}

	if book.Status != model.Available {
		return errors.New("cannot delete a book that is not available")
	}

	return s.bookRepo.Delete(id)
}

func (s *BookService) ListBooks(page, pageSize int) ([]*model.Book, int64, error) {
	return s.bookRepo.FindAll(page, pageSize)
}

func (s *BookService) SearchBooks(query string, page, pageSize int) ([]*model.Book, int64, error) {
	return s.bookRepo.Search(query, page, pageSize)
}

func (s *BookService) BorrowBook(userID, bookID uint) error {
	// 获取图书
	book, err := s.bookRepo.FindByID(bookID)
	if err != nil {
		return err
	}

	// 检查图书状态
	if book.Status != model.Available {
		return errors.New("book is not available for borrowing")
	}

	// 创建借阅记录
	record := &model.BorrowRecord{
		BookID:   bookID,
		UserID:   userID,
		BorrowAt: time.Now(),
		DueAt:    time.Now().Add(30 * 24 * time.Hour), // 30天后到期
		Status:   model.BorrowedStatus,
	}

	if err := s.borrowRepo.Create(record); err != nil {
		return err
	}

	// 更新图书状态
	return s.bookRepo.UpdateStatus(bookID, model.Borrowed)
}

func (s *BookService) ReturnBook(bookID uint) error {
	// 获取借阅记录
	record, err := s.borrowRepo.FindByBookID(bookID)
	if err != nil {
		return err
	}

	// 更新借阅记录
	now := time.Now()
	record.ReturnAt = &now
	record.Status = model.ReturnedStatus

	if err := s.borrowRepo.Update(record); err != nil {
		return err
	}

	// 更新图书状态
	return s.bookRepo.UpdateStatus(bookID, model.Available)
}
